import 'dart:collection';
import 'dart:core';

import 'package:decimal/decimal.dart';

import 'BaseBean.dart';
import 'BaseBean.map.dart';

typedef void MapTransToBeanFunc(BaseBean bean, Map<String, dynamic> json);
typedef void BeanTransToMapFunc(BaseBean bean, Map<String, dynamic> json);

var mapTarnsToBean = HashMap<String, MapTransToBeanFunc>();
var beanTransToMap = HashMap<String, BeanTransToMapFunc>();
void initMap2() {
  initTransBeanMap();
}

T generateBeanObject2<T>() {
  return generateBeanObject();
}

int? getValueToInt(dynamic? value) {
  if (value is String) {
    return int.tryParse(value);
  } else if (value is int) {
    return value;
  } else if (value is double) {
    return value.toInt();
  } else if (value is bool) {
    if (value) return 1;
    return 0;
  } else if (value is Decimal) {
    return value.toInt();
  } else {
    return null;
  }
}

double? getValueToDouble(dynamic? value) {
  if (value is String) {
    return double.tryParse(value);
  } else if (value is int) {
    return value.toDouble();
  } else if (value is double) {
    return value;
  } else if (value is bool) {
    if (value) return 1;
    return 0;
  } else if (value is Decimal) {
    return value.toDouble();
  } else {
    return null;
  }
}

Decimal? getValueToDecimal(dynamic? value) {
  if (value is String) {
    return Decimal.tryParse(value);
  } else if (value is int) {
    return Decimal.fromInt(value);
  } else if (value is double) {
    return Decimal.tryParse(value.toStringAsFixed(3));
  } else if (value is bool) {
    if (value) return Decimal.one;
    return Decimal.zero;
  } else if (value is Decimal) {
    return value;
  } else {
    return null;
  }
}

dynamic toValueFromDecimal(Decimal? value) {
  if (value == null) return null;
  return value.toDouble();
}

bool? getValueToBool(dynamic? value) {
  if (value is String) {
    return value.toLowerCase() == "true";
  } else if (value is int) {
    return value != 0;
  } else if (value is double) {
    return !value.isNaN && value != 0;
  } else if (value is bool) {
    return value;
  } else if (value is Decimal) {
    return !value.isNaN && value != Decimal.zero;
  } else {
    return null;
  }
}

String? getValueToString(dynamic? value) {
  if (value == null) {
    return null;
  }
  return value.toString();

  // if (value is String) {
  //   return value;
  // } else if (value is int) {
  //   return value.toString();
  // } else if (value is double) {
  //   return value.toStringAsFixed(3);
  // } else if (value is bool) {
  //   return value.toString();
  // } else if (value is Decimal) {
  //   return value.toString();
  // } else {
  //   return null;
  // }
}

T? getValueToBean<T extends BaseBean>(dynamic value) {
  if (value is Map<String, dynamic>) {
    var bean = generateBeanObject<T>();
    mapTarnsToBean[getTypeBaseString(T)]?.call(bean, value);
    return bean;
  } else {
    return null;
  }
}

dynamic toValueFromBean(BaseBean bean) => bean.toJson();

List<String?>? getValueToNullableStringList(dynamic value) {
  if (value is List) {
    List<String?> list = [];
    for (var item in value) {
      list.add(getValueToString(item));
    }
    return list;
  }
  return null;
}

dynamic toValueFromMap(Map<String, dynamic>? map) {
  if (map == null) return null;
  Map<String, dynamic> newMap = {};
  for (var item in map.entries) {
    if (item.value is BaseBean) {
      newMap[item.key] = toValueFromBean(item.value);
    } else if (item.value is Map<String, dynamic>) {
      newMap[item.key] = toValueFromMap(item.value);
    } else if (item.value is List<dynamic>) {
      newMap[item.key] = toValueFromList(item.value);
    } else {
      newMap[item.key] = item.value;
    }
  }
  return newMap;
}

List<String>? getValueToStringList(dynamic value) {
  if (value is List) {
    List<String> list = [];
    for (var item in value) {
      var m = getValueToString(item);
      if (m != null) list.add(m);
    }
    return list;
  }
  return null;
}

dynamic toValueFromList(List<dynamic>? list) {
  if (list == null) return null;
  List<dynamic> newList = [];
  for (var item in list) {
    if (item is BaseBean) {
      newList.add(toValueFromBean(item));
    } else if (item is Map<String, dynamic>) {
      newList.add(toValueFromMap(item));
    } else if (item is List<dynamic>) {
      newList.add(toValueFromList(item));
    } else {
      newList.add(item);
    }
  }
  return newList;
}

List<int?>? getValueToNullableIntList(dynamic value) {
  if (value is List) {
    List<int?> list = [];
    for (var item in value) {
      list.add(getValueToInt(item));
    }
    return list;
  }
  return null;
}

List<int>? getValueToIntList(dynamic value) {
  if (value is List) {
    List<int> list = [];
    for (var item in value) {
      var m = getValueToInt(item);
      if (m != null) list.add(m);
    }
    return list;
  }
  return null;
}

List<double?>? getValueToNullableDoubleList(dynamic value) {
  if (value is List) {
    List<double?> list = [];
    for (var item in value) {
      list.add(getValueToDouble(item));
    }
    return list;
  }
  return null;
}

List<double>? getValueToDoubleList(dynamic value) {
  if (value is List) {
    List<double> list = [];
    for (var item in value) {
      var m = getValueToDouble(item);
      if (m != null) list.add(m);
    }
    return list;
  }
  return null;
}

List<Decimal?>? getValueToNullableDecimalList(dynamic value) {
  if (value is List) {
    List<Decimal?> list = [];
    for (var item in value) {
      list.add(getValueToDecimal(item));
    }
    return list;
  }
  return null;
}

List<Decimal>? getValueToDecimalList(dynamic value) {
  if (value is List) {
    List<Decimal> list = [];
    for (var item in value) {
      var m = getValueToDecimal(item);
      if (m != null) list.add(m);
    }
    return list;
  }
  return null;
}

List<bool?>? getValueToNullableBoolList(dynamic value) {
  if (value is List) {
    List<bool?> list = [];
    for (var item in value) {
      list.add(getValueToBool(item));
    }
    return list;
  }
  return null;
}

List<bool>? getValueToBoolList(dynamic value) {
  if (value is List) {
    List<bool> list = [];
    for (var item in value) {
      var m = getValueToBool(item);
      if (m != null) list.add(m);
    }
    return list;
  }
  return null;
}

List<T?>? getValueToNullableBeanList<T extends BaseBean>(dynamic value) {
  if (value is List) {
    List<T?> list = [];
    for (var item in value) {
      var bean = getValueToBean<T>(item);
      list.add(bean);
    }
    return list;
  }
  return null;
}

List<T>? getValueToBeanList<T extends BaseBean>(dynamic value) {
  if (value is List) {
    List<T> list = [];
    for (var item in value) {
      var m = getValueToBean<T>(item);
      if (m != null) list.add(m);
    }
    return list;
  }
  return null;
}

Map<String, String?>? getValueToNullableStringMap(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, String?> map = {};
    for (var item in value.entries) {
      map[item.key] = getValueToString(item.value);
    }
    return map;
  }
  return null;
}

Map<String, String>? getValueToStringMap(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, String> map = {};
    for (var item in value.entries) {
      var m = getValueToString(item.value);
      if (m != null) map[item.key] = m;
    }
    return map;
  }
  return null;
}

Map<String, int>? getValueToIntMap(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, int> map = {};
    for (var item in value.entries) {
      var m = getValueToInt(item.value);
      if (m != null) map[item.key] = m;
    }
    return map;
  }
  return null;
}

Map<String, int?>? getValueToNullableIntMap(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, int?> map = {};
    for (var item in value.entries) {
      var m = getValueToInt(item.value);
      map[item.key] = m;
    }
    return map;
  }
  return null;
}

Map<String, double>? getValueToDoubleMap(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, double> map = {};
    for (var item in value.entries) {
      var m = getValueToDouble(item.value);
      if (m != null) map[item.key] = m;
    }
    return map;
  }
  return null;
}

Map<String, double?>? getValueToNullableDoubleMap(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, double?> map = {};
    for (var item in value.entries) {
      var m = getValueToDouble(item.value);
      map[item.key] = m;
    }
    return map;
  }
  return null;
}

Map<String, bool>? getValueToBoolMap(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, bool> map = {};
    for (var item in value.entries) {
      var m = getValueToBool(item.value);
      if (m != null) map[item.key] = m;
    }
    return map;
  }
  return null;
}

Map<String, bool?>? getValueToNullableBoolMap(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, bool?> map = {};
    for (var item in value.entries) {
      var m = getValueToBool(item.value);
      map[item.key] = m;
    }
    return map;
  }
  return null;
}

Map<String, Decimal>? getValueToDecimalMap(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, Decimal> map = {};
    for (var item in value.entries) {
      var m = getValueToDecimal(item.value);
      if (m != null) map[item.key] = m;
    }
    return map;
  }
  return null;
}

Map<String, Decimal?>? getValueToNullableDecimalMap(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, Decimal?> map = {};
    for (var item in value.entries) {
      var m = getValueToDecimal(item.value);
      map[item.key] = m;
    }
    return map;
  }
  return null;
}

Map<String, T>? getValueToBeanMap<T extends BaseBean>(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, T> map = {};
    for (var item in value.entries) {
      var m = getValueToBean<T>(item.value);
      if (m != null) map[item.key] = m;
    }
    return map;
  }
  return null;
}

Map<String, T?>? getValueToNullableBeanMap<T extends BaseBean>(dynamic value) {
  if (value is Map<String, dynamic>) {
    Map<String, T?> map = {};
    for (var item in value.entries) {
      var m = getValueToBean<T>(item.value);
      map[item.key] = m;
    }
    return map;
  }
  return null;
}
